import os
import pickle
from openpyxl import load_workbook
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from xlutils import copy
import xlrd as xlrd
from selenium import webdriver
from selenium.webdriver import ActionChains
import random
import time
from CONFIG.config import BASE_PATH

driver = webdriver.Chrome()
def chrome():
    driver.implicitly_wait(30)
    driver.maximize_window()
    return driver
def human_like_slide(slider_element, slide_distance, step_count=5):
    """
    模拟人类滑动行为的滑块操作

    参数:
        driver: WebDriver 实例
        slider_element: 滑块元素(WebElement)
        slide_distance: 需要滑动的总距离(像素)
        step_count: 滑动分几步完成(默认5步)

    返回:
        None
    """
    # 初始化动作链
    actions = ActionChains(driver)
    # 点击并按住滑块
    actions.click_and_hold(slider_element)
    # 计算每一步的基础距离和余数
    base_step = slide_distance // step_count
    remainder = slide_distance % step_count
    # 分段滑动
    for step in range(step_count):
        # 当前步的滑动距离(基础距离加上余数分配)
        current_step = base_step + (1 if step < remainder else 0)
        # 添加随机偏移(-5到+5像素)使行为更自然
        random_offset = random.randint(-5, 5)
        current_step += random_offset
        # 执行滑动
        actions.move_by_offset(current_step, 0)
        # 随机暂停(0.1-0.3秒)
        pause_time = random.uniform(0.1, 0.3)
        actions.pause(pause_time)
    # 释放滑块
    actions.release()
    # 执行所有动作
    actions.perform()
    # 滑动后随机等待(0.5-1.5秒)
    time.sleep(random.uniform(0.5, 1.5))

# def read_data_from_excel(file,sheet):
#     data = xlrd.open_workbook(file)
#     table=data.sheet_by_name(sheet)
#     nrows = table.nrows
#     ret=[]
#     for row in range(1,nrows):
#         data=table.row_values(row)
#         ret.append(data)
#     return ret



def read_data_from_excel(file, sheet_name):
    """
    读取excel数据
    :param file:
    :param sheet_name:
    :return:
    """
    try:
        # 加载工作簿
        workbook = load_workbook(file)
        # 获取指定工作表
        sheet = workbook[sheet_name]
        data = []
        # 从第二行开始遍历工作表的每一行
        for row in sheet.iter_rows(min_row=2, values_only=True):
            data.append(row)
        return data
    except FileNotFoundError:
        print(f"错误: 文件 {file} 未找到。")
    except KeyError:
        print(f"错误: 工作表 {sheet_name} 未找到。")
    except Exception as e:
        print(f"错误: 发生未知错误 - {e}")
    return []


def write_data_from_excel(sheet,data):
    """
    写入excel文件
    :param sheet:
    :param data:
    :return:
    """
    savepath =r'D:\pythonproject\考试系统后台\DATAS\data.xls'  # 已有xls的路径
    xls = xlrd.open_workbook(savepath, formatting_info=True)  # 得到文件
    wbook = copy.copy(xls)  # 复制文件并保留格式
    wsheet = wbook.get_sheet(sheet)  # 打开表单
    wsheet.write(1,0,data)  # n是行，i是列
    wbook.save(savepath)  # 最后进行保存


def get_cookies():
    """
    获取登录cookies
    :return:
    """
    cookies = driver.get_cookies()
    with open(os.path.join(BASE_PATH, "cookies.pkl"), "wb") as file:
        pickle.dump(cookies, file)

def load_cookies(url):
    """
    登录之后加载cookie到新url
    :param url:
    :return:
    """
    driver.get(url)  # 先访问域名
    # 加载cookies
    with open(os.path.join(BASE_PATH, "cookies.pkl"), "rb") as file:
        cookies = pickle.load(file)
    # 添加cookies
    for cookie in cookies:
        # 需要删除'domain'字段中的点，否则Selenium会报错
        if 'domain' in cookie:
            if cookie['domain'].startswith('.'):
                cookie['domain'] = cookie['domain'][1:]
        driver.add_cookie(cookie)
    # 刷新页面使cookies生效
    driver.refresh()





def select_nested_menu(*args):
    """
    多级菜单处理
    :param items:
    :return:
    """
    items = []
    for i in args:
        items.append(i)
    for item_text in items:
        # 当前层级菜单项定位
        item = WebDriverWait(driver, 10).until(
            EC.presence_of_element_located((By.XPATH, f"//li[contains(., '{item_text}')]"))
        )
        ActionChains(driver).move_to_element(item).perform()
        print(f"已展开菜单: {item_text}")
    # 最后点击最终选项
        item.click()
